/*
 * 描          述:  <描述>
 * 修  改   人:  Administrator
 * 修改时间:  2019年5月16日
 * <修改描述:>
 */
package com.tx.component.auth.context;

import java.util.List;
import java.util.Map;

import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.core.Ordered;

import com.tx.component.auth.model.Auth;
import com.tx.core.exceptions.util.AssertUtils;
import com.tx.core.util.CacheUtils;

/**
 * 权限类型业务层<br/>
 * <功能详细描述>
 * 
 * @author  Administrator
 * @version  [版本号, 2019年5月16日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
class CachingAuthManager implements AuthManager {
    
    private static final Class<?>[] FINDBYID_PARAMETER_TYPES = new Class<?>[] {
            String.class };
    
    private static final Class<?>[] QUERYLIST_PARAMETER_TYPES = new Class<?>[] {
            String.class, Map.class };
    
    //private static final Class<?>[] QUERYCHILDREN_PARAMETER_TYPES = new Class<?>[] {
    //        String.class };
    //
    //private static final Class<?>[] QUERYDESCENDANTS_PARAMETER_TYPES = new Class<?>[] {
    //        String.class };
    //private final Class<?> beanClass;
    
    /** 权限类型Manager的实际实现类 */
    private AuthManager delegate;
    
    /** 权限类型缓存 */
    private Cache authCache;
    
    /** 构造函数 */
    public CachingAuthManager(AuthManager delegate, Cache authCache) {
        this.delegate = delegate;
        this.authCache = authCache;
        
        AssertUtils.notNull(delegate, "delegate is null.");
        AssertUtils.notNull(authCache, "authCache is null.");
        
        //对象可能已经被代理，这里需要取到被代理的类
        //this.beanClass = ClassUtils.getUserClass(delegate);
        this.authCache.clear();
    }
    
    /**
     * @param roleTypeId
     * @return
     */
    @Override
    public Auth findAuthById(String authId) {
        String cacheKey = CacheUtils.generateStringCacheKey(this.delegate,
                AuthManager.class,
                "findAuthById",
                FINDBYID_PARAMETER_TYPES,
                new Object[] { authId });
        
        ValueWrapper vw = this.authCache.get(cacheKey);
        if (vw != null) {
            if (vw.get() != null && Auth.class.isInstance(vw.get())) {
                Auth roleType = (Auth) vw.get();
                return roleType;
            } else {
                return null;
            }
        }
        
        Auth auth = this.delegate.findAuthById(authId);
        //为null的时候依然缓存
        this.authCache.put(cacheKey, auth);
        return auth;
    }
    
    /**
     * @param authTypeId
     * @return
     */
    @Override
    public List<Auth> queryAuthList(String authTypeId,
            Map<String, Object> params) {
        String cacheKey = CacheUtils.generateStringCacheKey(this.delegate,
                AuthManager.class,
                "queryAuthList",
                QUERYLIST_PARAMETER_TYPES,
                new Object[] { authTypeId, params });
        
        ValueWrapper vw = this.authCache.get(cacheKey);
        if (vw != null && vw.get() != null && List.class.isInstance(vw.get())) {
            @SuppressWarnings("unchecked")
            List<Auth> resList = (List<Auth>) vw.get();
            return resList;
        }
        
        List<Auth> resList = this.delegate.queryAuthList(authTypeId, params);
        //为empty的时候依然缓存
        this.authCache.put(cacheKey, resList);
        return resList;
    }
    
    /**
     * 不从缓存取值，但是要向缓存中写入值
     * @param authTypeId
     * @param params
     * @return
     */
    @Override
    public List<Auth> queryAuthListWithoutCaching(String authTypeId,
            Map<String, Object> params) {
        String cacheKey = CacheUtils.generateStringCacheKey(this.delegate,
                AuthManager.class,
                "queryAuthList",
                QUERYLIST_PARAMETER_TYPES,
                new Object[] { authTypeId, params });
        
        List<Auth> resList = this.delegate
                .queryAuthListWithoutCaching(authTypeId, params);
        //为empty的时候依然缓存
        this.authCache.put(cacheKey, resList);
        return resList;
    }
    
    /**
     * @return
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
    
    ///**
    // * @param parentId
    // * @param authTypeId
    // * @return
    // */
    //@Override
    //public List<Auth> queryChildrenAuthByParentId(String parentId) {
    //    String cacheKey = CacheUtils.generateStringCacheKey(this.beanClass,
    //            "queryChildrenAuthByParentId",
    //            QUERYCHILDREN_PARAMETER_TYPES,
    //            new Object[] { parentId });
    //    
    //    ValueWrapper vw = this.authCache.get(cacheKey);
    //    if (vw != null && vw.get() != null && List.class.isInstance(vw.get())) {
    //        @SuppressWarnings("unchecked")
    //        List<Auth> resList = (List<Auth>) vw.get();
    //        return resList;
    //    }
    //    
    //    List<Auth> resList = this.delegate
    //            .queryChildrenAuthByParentId(parentId);
    //    if (!CollectionUtils.isEmpty(resList)) {
    //        this.authCache.put(cacheKey, resList);
    //    }
    //    return resList;
    //}
    //
    ///**
    // * @param parentId
    // * @param authTypeId
    // * @return
    // */
    //@Override
    //public List<Auth> queryDescendantsAuthByParentId(String parentId) {
    //    String cacheKey = CacheUtils.generateStringCacheKey(this.beanClass,
    //            "queryDescendantsAuthByParentId",
    //            QUERYDESCENDANTS_PARAMETER_TYPES,
    //            new Object[] { parentId });
    //    
    //    ValueWrapper vw = this.authCache.get(cacheKey);
    //    if (vw != null && vw.get() != null && List.class.isInstance(vw.get())) {
    //        @SuppressWarnings("unchecked")
    //        List<Auth> resList = (List<Auth>) vw.get();
    //        return resList;
    //    }
    //    
    //    List<Auth> resList = this.delegate
    //            .queryChildrenAuthByParentId(parentId);
    //    //为empty的时候依然缓存
    //    this.authCache.put(cacheKey, resList);
    //    return resList;
    //}
    //
    ///**
    // * @param parentId
    // * @param params
    // * @return
    // */
    //@Override
    //public List<Auth> queryChildrenAuthByParentIdWithoutCaching(String parentId,
    //        Map<String, Object> params) {
    //    List<Auth> resList = this.delegate
    //            .queryChildrenAuthByParentIdWithoutCaching(parentId, params);
    //    return resList;
    //}
    //
    ///**
    // * @param parentId
    // * @param params
    // * @return
    // */
    //@Override
    //public List<Auth> queryDescendantsAuthByParentIdWithoutCaching(
    //        String parentId, Map<String, Object> params) {
    //    List<Auth> resList = this.delegate
    //            .queryDescendantsAuthByParentIdWithoutCaching(parentId, params);
    //    return resList;
    //}
    
}
